<template>
  <div class="log-container">
    <!-- 表格区域 -->
    <el-card shadow="never" class="table-card">
      <div class="table-wrapper">
        <el-table
          :data="logList"
          v-loading="loading"
          stripe
          border
          :row-class-name="tableRowClassName"
          style="width: 100%"
          :max-height="tableHeight"
        >
          <!-- 序号列 -->
          <el-table-column label="#" width="60" align="center">
            <template #default="{ $index }">
              <span class="index-badge">
                {{ (pagination.page - 1) * pagination.pageSize + $index + 1 }}
              </span>
            </template>
          </el-table-column>

          <el-table-column prop="operateTime" label="操作时间" width="165" align="center">
            <template #default="{ row }">
              <div class="time-cell">
                <span class="date">{{ formatDate(row.operateTime) }}</span>
                <span class="time">{{ formatTime(row.operateTime) }}</span>
              </div>
            </template>
          </el-table-column>

          <!-- 操作人ID列 -->
          <el-table-column prop="operateEmpId" label="操作人" width="100" align="center">
            <template #default="{ row }">
              <el-tag type="info" size="small">ID:{{ row.operateEmpId }}</el-tag>
            </template>
          </el-table-column>

          <el-table-column prop="className" label="类名" min-width="180" show-overflow-tooltip>
            <template #default="{ row }">
              <div class="class-name">
                <span class="package">{{ getPackageName(row.className) }}</span>
                <span class="name">{{ getSimpleClassName(row.className) }}</span>
              </div>
            </template>
          </el-table-column>

          <el-table-column prop="methodName" label="方法名" min-width="120">
            <template #default="{ row }">
              <el-tag effect="plain" type="primary" size="small">{{ row.methodName }}</el-tag>
            </template>
          </el-table-column>

          <el-table-column prop="methodParams" label="参数" min-width="150" show-overflow-tooltip>
            <template #default="{ row }">
              <el-tag v-if="row.methodParams === '[]'" type="info" size="small">无参数</el-tag>
              <el-tag v-else type="warning" size="small" @click="showDetail(row)">
                {{ truncateText(row.methodParams, 15) }}
              </el-tag>
            </template>
          </el-table-column>

          <el-table-column prop="costTime" label="耗时" width="90" align="center">
            <template #default="{ row }">
              <el-tooltip :content="`${row.costTime}ms`" placement="top">
                <el-progress
                  :percentage="getTimePercentage(row.costTime)"
                  :stroke-width="12"
                  :color="getTimeColor(row.costTime)"
                  :show-text="false"
                />
              </el-tooltip>
            </template>
          </el-table-column>

          <el-table-column prop="returnValue" label="返回值" min-width="150" show-overflow-tooltip>
            <template #default="{ row }">
              <el-tag
                v-if="row.returnValue"
                :type="getReturnType(row.returnValue)"
                size="small"
                @click="showDetail(row)"
              >
                {{ truncateText(row.returnValue, 20) }}
              </el-tag>
              <span v-else>-</span>
            </template>
          </el-table-column>

          <el-table-column fixed="right" label="操作" width="100" align="center">
            <template #default="{ row }">
              <el-button type="primary" size="small" plain @click="showDetail(row)">详情</el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>

      <!-- 分页组件 -->
      <div class="pagination-container">
        <el-pagination
          v-model:current-page="pagination.page"
          v-model:page-size="pagination.pageSize"
          :page-sizes="[10, 20, 50, 100]"
          :total="pagination.total"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handlePageSizeChange"
          @current-change="handlePageChange"
        />
      </div>
    </el-card>

    <!-- 日志详情弹窗 -->
    <el-dialog v-model="detailDialogVisible" title="日志详情" width="55%" class="detail-dialog">
      <div class="detail-content" v-if="currentLog">
        <div class="detail-header">
          <div class="method-info">
            <el-tag type="primary" size="large">{{ currentLog.methodName }}</el-tag>
            <span class="class-name">{{ currentLog.className }}</span>
          </div>
          <div class="time-info">
            <el-tag type="info" size="large">
              <i class="el-icon-time"></i>
              {{ formatDateTime(currentLog.operateTime) }}
            </el-tag>
            <el-tag :type="getTimeTagType(currentLog.costTime)" size="large">
              <i class="el-icon-timer"></i>
              {{ currentLog.costTime }}ms
            </el-tag>
          </div>
        </div>

        <div class="detail-body">
          <div class="detail-section">
            <h3><i class="el-icon-user"></i> 操作人</h3>
            <el-tag type="info" size="large">ID: {{ currentLog.operateEmpId }}</el-tag>
          </div>

          <div class="detail-section">
            <h3><i class="el-icon-s-operation"></i> 参数</h3>
            <div class="scrollable-content">
              <pre
                v-highlight
              ><code class="json">{{ formatJson(currentLog.methodParams) }}</code></pre>
            </div>
          </div>

          <div class="detail-section">
            <h3><i class="el-icon-s-claim"></i> 返回值</h3>
            <div class="scrollable-content">
              <pre
                v-highlight
              ><code class="json">{{ formatJson(currentLog.returnValue) }}</code></pre>
            </div>
          </div>
        </div>
      </div>
      <template #footer>
        <el-button @click="detailDialogVisible = false">关闭</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue'
import { ElMessage } from 'element-plus'
import type { OperateLog } from '@/api/log'
import { queryPageApi } from '@/api/log'
import dayjs from 'dayjs'

// 日志列表数据
const logList = ref<OperateLog[]>([])
const loading = ref(false)
const pagination = reactive({
  page: 1,
  pageSize: 10,
  total: 0,
})

// 详情弹窗相关
const detailDialogVisible = ref(false)
const currentLog = ref<OperateLog | null>(null)

// 计算表格高度（响应式）
const tableHeight = computed(() => {
  // 根据页面高度动态计算表格高度，确保分页组件始终可见
  const windowHeight = window.innerHeight
  // 减去顶部导航、卡片边距、分页高度等
  return windowHeight - 220
})

// 初始化时获取日志数据
onMounted(() => {
  fetchLogs()
  // 监听窗口大小变化
  window.addEventListener('resize', handleResize)
})

// 处理窗口大小变化
const handleResize = () => {
  // 重新计算表格高度
  // 这里不需要额外操作，因为tableHeight是computed属性，会自动更新
}

// 获取日志数据
const fetchLogs = async () => {
  try {
    loading.value = true

    // 关键修复：确保传递正确的分页参数
    const response = await queryPageApi({
      page: pagination.page,
      pageSize: pagination.pageSize,
    })

    if (response.code === 1) {
      logList.value = response.data.rows
      pagination.total = response.data.total
    } else {
      ElMessage.error(response.msg || '获取日志数据失败')
    }
  } catch (error) {
    console.error('请求日志数据出错:', error)
    ElMessage.error('服务器错误，请稍后重试')
  } finally {
    loading.value = false
    // 滚动到表格顶部
    scrollToTableTop()
  }
}

// 滚动到表格顶部
const scrollToTableTop = () => {
  const tableWrapper = document.querySelector('.table-wrapper')
  if (tableWrapper) {
    tableWrapper.scrollTop = 0
  }
}

// 处理分页大小变化
const handlePageSizeChange = (size: number) => {
  pagination.pageSize = size
  pagination.page = 1 // 重置到第一页
  fetchLogs()
}

// 处理页码变化
const handlePageChange = (page: number) => {
  pagination.page = page
  fetchLogs()
}

// 显示日志详情
const showDetail = (log: OperateLog) => {
  currentLog.value = log
  detailDialogVisible.value = true
}

// 格式化日期时间
const formatDateTime = (dateTime: string) => {
  return dayjs(dateTime).format('YYYY-MM-DD HH:mm:ss')
}

// 单独格式化日期
const formatDate = (dateTime: string) => {
  return dayjs(dateTime).format('MM-DD')
}

// 单独格式化时间
const formatTime = (dateTime: string) => {
  return dayjs(dateTime).format('HH:mm:ss')
}

// 根据耗时获取标签类型
const getTimeTagType = (time: number) => {
  if (time < 50) return 'success'
  if (time < 200) return 'warning'
  return 'danger'
}

// 获取耗时进度条颜色
const getTimeColor = (time: number) => {
  if (time < 50) return '#67C23A'
  if (time < 200) return '#E6A23C'
  return '#F56C6C'
}

// 获取耗时百分比（用于进度条）
const getTimePercentage = (time: number) => {
  if (time > 1000) return 100
  return Math.min(time / 10, 100)
}

// 格式化JSON字符串
const formatJson = (str: string) => {
  try {
    // 尝试解析为JSON对象
    const obj = JSON.parse(str)
    return JSON.stringify(obj, null, 2)
  } catch (e) {
    // 如果不是JSON格式，直接返回原始字符串
    return str
  }
}

// 文本截断函数
const truncateText = (text: string, maxLength: number) => {
  if (!text) return ''
  return text.length > maxLength ? text.substring(0, maxLength) + '...' : text
}

// 获取返回值的类型标签
const getReturnType = (value: string) => {
  try {
    const obj = JSON.parse(value)
    if (obj === null) return 'info'
    if (Array.isArray(obj)) return 'success'
    if (typeof obj === 'object') return 'warning'
    return ''
  } catch {
    return ''
  }
}

// 获取类名的简单形式（去掉包名）
const getSimpleClassName = (className: string) => {
  const parts = className.split('.')
  return parts[parts.length - 1]
}

// 获取包名
const getPackageName = (className: string) => {
  const parts = className.split('.')
  if (parts.length > 1) {
    parts.pop()
    return parts.join('.') + '.'
  }
  return ''
}

// 表格行样式
const tableRowClassName = ({ row }: { row: OperateLog; rowIndex: number }) => {
  if (row.costTime > 500) return 'warning-row'
  if (row.costTime > 1000) return 'danger-row'
  return ''
}
</script>

<style scoped lang="scss">
.log-container {
  padding: 16px;
  height: 100vh;
  box-sizing: border-box;
  background: #f0f2f5;
  display: flex;
  flex-direction: column;

  .table-card {
    flex: 1;
    display: flex;
    flex-direction: column;
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);

    :deep(.el-card__body) {
      padding: 0;
      display: flex;
      flex-direction: column;
      height: 100%;
    }

    .table-wrapper {
      flex: 1;
      overflow: auto;
      position: relative;

      .el-table {
        font-size: 13px;

        :deep(th) {
          background-color: #f8f9fa;
          font-weight: 600;
          color: #495057;
          position: sticky;
          top: 0;
          z-index: 1;
        }

        :deep(.el-table__row) {
          transition: background-color 0.2s;

          &:hover {
            background-color: #f8f9fa !important;
          }

          td {
            padding: 8px 0;
          }
        }

        .warning-row {
          background-color: #fff8e6;
        }

        .danger-row {
          background-color: #fff0f0;
        }
      }
    }

    .index-badge {
      display: inline-block;
      width: 24px;
      height: 24px;
      line-height: 24px;
      border-radius: 50%;
      background: #f0f2f5;
      color: #606266;
      font-size: 12px;
      text-align: center;
    }

    .time-cell {
      display: flex;
      flex-direction: column;
      align-items: center;

      .date {
        font-size: 12px;
        color: #909399;
      }

      .time {
        font-size: 13px;
        font-weight: 500;
        color: #495057;
      }
    }

    .class-name {
      display: flex;
      flex-direction: column;

      .package {
        font-size: 11px;
        color: #909399;
        overflow: hidden;
        text-overflow: ellipsis;
      }

      .name {
        font-weight: 500;
        color: #495057;
      }
    }

    .pagination-container {
      padding: 16px;
      background: #fff;
      border-top: 1px solid #ebeef5;
      position: sticky;
      bottom: 0;
      z-index: 2;
    }
  }
}

.detail-dialog {
  :deep(.el-dialog__body) {
    padding: 0;
  }

  .detail-content {
    padding: 0 20px;

    .detail-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 16px 0;
      border-bottom: 1px solid #ebeef5;
      margin-bottom: 16px;

      .method-info {
        display: flex;
        align-items: center;
        gap: 12px;

        .class-name {
          font-size: 14px;
          color: #606266;
        }
      }

      .time-info {
        display: flex;
        gap: 8px;
      }
    }

    .detail-body {
      .detail-section {
        margin-bottom: 20px;

        h3 {
          margin: 0 0 12px 0;
          font-size: 15px;
          color: #606266;
          display: flex;
          align-items: center;
          gap: 6px;

          i {
            font-size: 16px;
          }
        }
      }
    }
  }
}

.scrollable-content {
  max-height: 300px;
  overflow: auto;
  border: 1px solid #ebeef5;
  border-radius: 4px;
  padding: 12px;
  background-color: #fafafa;

  pre {
    margin: 0;
    font-family: 'Fira Code', 'Consolas', monospace;
    font-size: 13px;
    line-height: 1.5;
  }
}

.el-tag {
  cursor: pointer;
  transition: all 0.2s;

  &:hover {
    opacity: 0.8;
    transform: translateY(-1px);
  }
}

:deep(.el-progress-bar) {
  padding-right: 0;
  margin-right: 0;
}
</style>
